<template>
<!--  角色列表-->
  <div class="page">
    <!-- 条件筛选 -->
    <div class="page_filter">
      <el-input v-model="form.name" clearable placeholder="请输入角色名称"></el-input>
      <el-button class="common_btn-defalut" icon="el-icon-search" @click="form.page=1;queryList()">搜索</el-button>
    </div>
    <div class="page_main">
      <el-button icon="el-icon-plus" @click.stop="handleAdd" class="common_btn-small">添加角色</el-button>
      <!-- table -->
      <div class="common_btnBox" >
        <i class="iconfont iconzongshu icon-size"></i>
        总数：{{form.total}}
      </div>
      <el-table
        :data="tableList"
        border>
        <el-table-column
          label="序号"
          fixed
          width="80">
          <template slot-scope="scope">
            {{getIndex(scope.$index)}}
          </template>
        </el-table-column>
        <el-table-column
          prop="name"
          label="角色名称"
          width="200"
          sortable>
        </el-table-column>
        <el-table-column
          prop="platformTypeName"
          label="关联平台类型"
          width="180"
          sortable>
        </el-table-column>
        <el-table-column
          prop="description"
          label="角色说明">
        </el-table-column>
        <el-table-column
          prop="createTime"
          width="180"
          label="创建时间">
          <template slot-scope="scope">{{scope.row.createTime | formatTimer}}</template>
        </el-table-column>
        <el-table-column
          prop="createTime"
          width="180"
          label="更新时间">
          <template slot-scope="scope">{{scope.row.updateTime | formatTimer}}</template>
        </el-table-column>
        <el-table-column
          label="操作"
          fixed="right"
          width="240">
          <template slot-scope="scope" >
            <button class="btn_edit" @click="handleEdit(scope.row)">编辑</button>
            <button class="btn_edit" @click="_handleRelated(scope.row)">关联菜单</button>
            <el-popconfirm
              confirmButtonText='好的'
              cancelButtonText='不用了'
              icon=""
              title="确定删除该角色吗？"
              @confirm="handleDelete(scope.row)"
            >
              <button slot="reference"  class="btn_delete">删除</button>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>
      <!-- 分页器 -->
      <el-pagination
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        :current-page="form.page"
        :page-size="form.pageSize"
           :page-sizes="[10, 20, 30, 40,50,60,70,80,90,100]"
              layout="sizes, prev, pager, next"
        :total="form.total">
      </el-pagination>
    </div>
    <!-- 新增编辑弹窗 -->
    <el-dialog
      :title="dialogTitle"
      :visible.sync="isShowDialog"
      :close-on-click-modal="false"
      width="520px">
      <!-- 具体form表单 -->
      <el-form label-position="right" ref="form" :rules="rules" :model="currentRow" label-width="80px">
        <el-form-item label="角色名称" prop="name">
          <el-input v-model="currentRow.name" placeholder="输入角色名称" :maxlength="20"></el-input>
        </el-form-item>
        <el-form-item v-if="isShowSelect" label="平台类型"  prop="platformAuthority">
          <el-select v-model.trim="currentRow.platformType" clearable placeholder="关联对应平台类型，自动生成初始角色">
            <el-option
              v-for="item in EnumUnitTypeList"
              :key="item.code"
              :label="item.name"
              :value="item.code"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="角色说明">
          <el-input v-model="currentRow.description" placeholder="输入角色说明"></el-input>
        </el-form-item>
      </el-form>
      <!-- 操作按钮 -->
      <span slot="footer" class="dialog-footer">
        <el-button class="common_btn-white" @click="isShowDialog = false">取消</el-button>
        <el-button class="common_btn-defalut" type="primary" @click="validateForm">确定</el-button>
      </span>
    </el-dialog>

    <!-- 关联菜单 -->
    <el-dialog
      title="关联菜单"
      custom-class="dialog_relate"
      :visible.sync="isShowRelateDialog"
      :before-close="_closeTreeDialog"
      width="700px">
      <!-- 具体form表单 -->
      <div class="dialog_filter">
        <el-input v-model="treeSearch" clearable placeholder="搜索菜单名称"></el-input>
        <el-button class="common_btn-defalut" icon="el-icon-search" @click="_filterTreeNode">搜索</el-button>
      </div>
      <el-scrollbar class="tree_scroll common_scrollbar">
        <el-tree
          :check-strictly="true"
          :data="treeList"
          show-checkbox
          node-key="id"
          ref="tree"
          @check="_checkChange"
          class="role_tree"
          :props="defaultProps"
          :default-expanded-keys="expandedList"
          :filter-node-method="filterNode">
        </el-tree>
      </el-scrollbar>
      <!-- 操作按钮 -->
      <span slot="footer" class="dialog-footer">
        <el-button class="common_btn-white" @click="_closeTreeDialog">取消</el-button>
        <el-button  class="common_btn-defalut" type="primary" @click="_getTreeList">确定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import { roleQuery, roleAdd, roleUpdate, roleDelete, roleRelMenus, roleMenuIdList } from '@/services/model/authority-mgmt'
import { getDictData } from '@/services/model/common'
import Format from '@/utils/format'

// form表单校验规则
const RULES = {
  name: { required: true, message: '请输入角色名称' }
}
export default {
  data () {
    return {
      form: {
        page: 1,
        pageSize: 10
      },
      rules: RULES, // 表单校验的规则
      tableList: [],
      isShowDialog: false, // 是否显示弹窗
      isShowRelateDialog: false, // 是否显示关联菜单弹窗
      currentRow: {}, // 新增数据
      defaultProps: {
        children: 'subMenu',
        label: 'name',
      },
      treeSearch: '',
      //平台角色列表 接口获取
      EnumUnitTypeList: [],
      // 默认展开的节点
      expandedList: [],
      isShowSelect: false,
      userInfo:''
    }
  },
  computed: {
    firstData() {
      return this.$store.state.userInfo
    },
    // 取菜单列表
    treeList () {
      return this.$store.state.nodeList
    },
    // 弹窗的title
    dialogTitle () {
      return this.currentRow.id ? '编辑角色' : '新增角色'
    },
  },
  watch: {
    firstData(val) {
      this.userInfo = val
    },
  },
  filters: {
    // 时间格式化
    formatTimer (timer) {
      return Format(new Date(timer), 'yyyy-MM-dd hh:mm:ss')
    },
  },
  methods: {
    // 通用获取枚举方法
    async queryDictData (enumName, model) {
      const { data } = await getDictData({ enumName })
      if (model) this[model] = data || []
      return data || []
    },
    // 当前变化的节点
    // checked点击的状态
    _checkChange (data, checkedList, c) {
      // 获取当前勾选的数组
      let checked = checkedList.checkedKeys.includes(data.id)
      // 当前节点下所包含的所有子节点
      let idsList = []
      // 递归将树形数据扁平化
      let _loop = list => {
        list.map(x => {
          idsList.push(x.id)
          x.subMenu?.length && _loop(x.subMenu)
        })
      }
      _loop([data])
      idsList.map(x => {
        // 对子节点进行设置
        this.$refs.tree.setChecked(x, checked)
      })
    },
    // 关闭关联菜单弹窗
    _closeTreeDialog () {
      this.treeSearch = ''
      this._filterTreeNode()
      this.isShowRelateDialog = false
    },
    // 点击过滤
    _filterTreeNode () {
      this.$refs.tree.filter(this.treeSearch)
    },
    // 过滤节点
    filterNode (value, data) {
      if (!value) return true
      return data.name.indexOf(value) !== -1
    },
    // 获取tree勾选节点
    async _getTreeList () {
      // 获取勾选的节点
      let checked = this.$refs.tree.getCheckedKeys()
      // 此方法获取半选节点
      let halfChecked = this.$refs.tree.getHalfCheckedKeys()
      // 获取当前勾选和半勾选的数据
      let menuIds = checked.concat(halfChecked)
      this.currentRow = { roleId: this.currentRow.id, menuIdList: menuIds }
      await roleRelMenus(this.currentRow)
      this.isShowRelateDialog = false
      this.$notify({
        type: 'success',
        title: '提示',
        message: '菜单已关联'
      })
    },
    // 显示关联菜单
    async _handleRelated (row) {
      this.currentRow = JSON.parse(JSON.stringify(row))
      // 将勾选的父级节点踢出
      // let list = this._filterTreeList()
      // let { menuIdList } = this.currentRow
      const { data } = await roleMenuIdList({ id: this.currentRow.id })
      let list = data || []
      this.expandedList = list
      this.isShowRelateDialog = true
      this.$nextTick(() => {
        this.$refs.tree.setCheckedKeys(list)
      })
    },
    // 如果该父级含有子集，则将父级id提出
    _filterTreeList () {
      let { menuIds, resourceIds } = this.currentRow
      // 递归剔除含有子集的父节点
      let _resetMenu = list => {
        list.map(x => {
          let index = menuIds.indexOf(x.id)
          // 有子集，并且在menuIds中存在，则比删除
          x.subMenu?.length && index !== -1 && menuIds.splice(index, 1)
          // 只要url不存在，并且有子集 则进行递归 由于第二级菜单必定含有 url. 所以不会遍历第三级
          !x.url && x.subMenu?.length && _resetMenu(x.subMenu)
        })
        return list
      }
      _resetMenu(this.treeList)
      return [...menuIds, ...resourceIds]
    },
    // 获取当前的序号
    getIndex (index) {
      let param = (this.form.page - 1) * this.form.pageSize + index + 1
      return param
    },
    // 分页大小改变
    handleSizeChange (val) {
      this.form.pageSize = val
      this.queryList()
    },

    // 当前页码改变
    handleCurrentChange (val) {
      this.form.page = val
      this.queryList()
    },
    // 表单提交
    validateForm () {
      this.$refs.form.validate((valid) => {
        if (valid) {
          this.submitData()
        }
      })
    },
    // 新增编辑提交数据
    async submitData () {
      // 根据ID判断使用新增还是编辑
      let action = this.currentRow.id ? roleUpdate : roleAdd
      let res = await action(this.currentRow)
      if (res.code === 200) {
        this.$notify({
          type: 'success',
          title: '提示',
          message: this.currentRow.id ? '修改成功' : '添加成功'
        })
        this.isShowDialog = false
        this.queryList()
        return true
      }
    },
    // 处理删除
    async handleDelete (row) {
      let res = await roleDelete({ id: row.id })
      if (res.code === 200) {
        this.$notify({
          type: 'success',
          title: '提示',
          message: '数据已删除'
        })
        this.queryList()
      }
    },
    // 新增数据
    handleAdd () {
      this.currentRow = {
        name: '',
        description: null
      }
      this.isShowDialog = true
      this.$nextTick(() => { this.$refs.form.clearValidate() })
    },
    /**
     * row  当前操作行的对象
     */
    handleEdit (row) {
      this.currentRow = JSON.parse(JSON.stringify(row))
      this.isShowDialog = true
      this.$nextTick(() => { this.$refs.form.clearValidate() })
    },
    async queryList () {
      // 由于在前端进行过滤，所以name不能传到后端
      let res = await roleQuery(this.form)
      this.tableList = res.data?.records || []
      this.form.page = Number(res.data?.current)
      this.form.total = Number(res.data?.total)
    }
  },
  mounted () {
    this.userInfo = this.firstData
    //超级管理员添加角色展示
    if(this.userInfo.type !== 4&&this.userInfo.type !== 5){
      this.isShowSelect = true
    }
    this.queryDictData('EnumUnitType','EnumUnitTypeList')
  },
  activated () {
    this.queryList()
  }
}
</script>

<style lang="less" scoped>
  .dialog_relate {
    .dialog_filter {
      display: flex;
      margin-bottom: 22px;
      .el-input {
        margin-right: 10px;
        width: 200px;
      }
    }
  }
  /deep/.tree_scroll .el-scrollbar__wrap {
    max-height: 50vh;
    height: 300px;
  }
  /deep/.role_tree {
    .el-checkbox__input.is-checked .el-checkbox__inner, .el-checkbox__input.is-indeterminate .el-checkbox__inner {
      background-color: #0DC26B;
      border-color: #0DC26B;
    }
    .el-checkbox__inner:hover {
      border-color: #0DC26B;
    }
  }
</style>
